package com.eleventwelve.iris.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.opentides.bean.SystemCodes;
import org.opentides.editor.BaseEntityEditor;
import org.opentides.service.SystemCodesService;
import org.opentides.util.StringUtil;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.eleventwelve.iris.entity.MedicalProcedure;
import com.eleventwelve.iris.entity.Medicine;
import com.eleventwelve.iris.entity.Patient;
import com.eleventwelve.iris.entity.PrescribedMedicine;
import com.eleventwelve.iris.entity.Prescription;
import com.eleventwelve.iris.entity.Staff;
import com.eleventwelve.iris.entity.Treatment;
import com.eleventwelve.iris.service.MedicalProcedureService;
import com.eleventwelve.iris.service.MedicineService;
import com.eleventwelve.iris.service.PatientService;
import com.eleventwelve.iris.service.PrescribedMedicineService;
import com.eleventwelve.iris.service.PrescriptionService;
import com.eleventwelve.iris.service.StaffService;
import com.eleventwelve.iris.service.TreatmentService;

/**
 * 
 * @author Ashley
 *
 */
@SuppressWarnings("deprecation")
public class TreatmentFormController extends SimpleFormController{
	private PatientService patientService;
	private SystemCodesService systemCodesService;
	private MedicalProcedureService medicalProcedureService;
	private StaffService staffService;
	private TreatmentService treatmentService;
	private PrescriptionService prescriptionService;
	private MedicineService medicineService;
	private PrescribedMedicineService prescribedMedicineService;
	
	
	@Override
	protected Map<String, Object> referenceData(HttpServletRequest request, Object command,
			Errors errors) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("procedures", medicalProcedureService.findAll());
		map.put("staffs", staffService.findAll());
		map.put("resultStatuses", systemCodesService.findSystemCodesByCategory("RESULT_STATUS"));
		map.put("medicines", medicineService.findAll());
		
		return map;
	}
	
	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		Treatment treatment = new Treatment();
		
		String treatmentId = request.getParameter("id");
		if(!StringUtil.isEmpty(treatmentId) && StringUtils.isNumeric(treatmentId)){
			treatment = treatmentService.load(treatmentId);
		} else {
			Patient patient = loadPatient(request.getParameter("patientId"));
			if(patient!=null){
				treatment.setPatient(patient);
			}
		}
		
		
		return treatment;
	}
	
	@Override
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(MedicalProcedure.class, new BaseEntityEditor(medicalProcedureService));
		binder.registerCustomEditor(SystemCodes.class, new BaseEntityEditor(systemCodesService));
		binder.registerCustomEditor(Patient.class, new BaseEntityEditor(patientService));
		binder.registerCustomEditor(Staff.class, new BaseEntityEditor(staffService));
		binder.registerCustomEditor(Medicine.class, new BaseEntityEditor(medicineService));
		
	}
	
	
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		
		String action = request.getParameter("action");
		
		
		Treatment treatment = (Treatment) command;
		Prescription prescription = treatment.getPrescription();
		
		
		List<PrescribedMedicine> toDelete = new ArrayList<PrescribedMedicine>();
		List<PrescribedMedicine> prescribedMedicines = prescription.getPrescribedMedicines();
		if(prescribedMedicines!=null && prescribedMedicines.size()>0){
			for (PrescribedMedicine prescribedMedicine : prescribedMedicines) {
				if(!prescribedMedicine.getIsDeleted() && prescribedMedicine.getMedicine()!=null){
					prescribedMedicine.setPrescription(prescription);
				} else {
					toDelete.add(prescribedMedicine);
				}
			}
			
			prescribedMedicines.removeAll(toDelete);
			for (PrescribedMedicine prescribedMedicine : toDelete) {
				if(prescribedMedicine.getId()!=null){
					prescribedMedicineService.delete(prescribedMedicine.getId());
				}
				
			}
		}
		
		treatmentService.save(treatment);
		prescriptionService.save(prescription);
		
		
		return new ModelAndView("redirect:/treatment.jspx?action="+action+"&id="+treatment.getId());
	}
	
	private Patient loadPatient(String patientId){
		Patient patient = null;
		if(!StringUtil.isEmpty(patientId)){
			patient = patientService.load(patientId);
		}
		return patient;
	}

	public PatientService getPatientService() {
		return patientService;
	}

	public void setPatientService(PatientService patientService) {
		this.patientService = patientService;
	}

	public SystemCodesService getSystemCodesService() {
		return systemCodesService;
	}

	public void setSystemCodesService(SystemCodesService systemCodesService) {
		this.systemCodesService = systemCodesService;
	}

	public MedicalProcedureService getMedicalProcedureService() {
		return medicalProcedureService;
	}

	public void setMedicalProcedureService(MedicalProcedureService medicalProcedureService) {
		this.medicalProcedureService = medicalProcedureService;
	}

	public StaffService getStaffService() {
		return staffService;
	}

	public void setStaffService(StaffService staffService) {
		this.staffService = staffService;
	}

	public TreatmentService getTreatmentService() {
		return treatmentService;
	}

	public void setTreatmentService(TreatmentService treatmentService) {
		this.treatmentService = treatmentService;
	}

	public PrescriptionService getPrescriptionService() {
		return prescriptionService;
	}

	public void setPrescriptionService(PrescriptionService prescriptionService) {
		this.prescriptionService = prescriptionService;
	}

	public MedicineService getMedicineService() {
		return medicineService;
	}

	public void setMedicineService(MedicineService medicineService) {
		this.medicineService = medicineService;
	}

	public PrescribedMedicineService getPrescribedMedicineService() {
		return prescribedMedicineService;
	}

	public void setPrescribedMedicineService(PrescribedMedicineService prescribedMedicineService) {
		this.prescribedMedicineService = prescribedMedicineService;
	}
	
}
